if(typeof QS=='undefined'){
	var QS={};
}
if(typeof QS_LOADER=='undefined'){
	var QS_LOADER = new QS.FileLoader({loadXMLConfig:{autoInit:false,xmlURL:'../js/sys/modulefiles.xml'}});
}
QS.ModuleBuilder=function(config){
	config=config||{};
	if(config.containerId){
		this.body=document.getElementById(config.containerId);
	}else{
		this.body=document.body;
	}
	this.$body=$(this.body);
	this.config=config;
	this.lastCallbackHeight=0;
	/*this.widgetFileList={10:['../js/language/en_us/qs_quote_en_us.js','../js/com/quote.js'],
	'0':['watchlist/watchlist_DataManager.js','watchlist/config.js','watchlist/watchlist_customview.js','watchlist/watchlist.js','watchlist/watchlist_contextmenu.js'],
	'2':['../js/com/news_DataManager.js','../js/com/news.js'],
	'1':['../js/language/en_us/qs_chart_en_us.js','../js/formatter/qs_formatter_en_us.js','../qschart/mstar_qs_chart_1.4.js','../qschart/simpleAutoCompleteBox.js','../qschart/webChart.js'],
	'14_1':['../lib/minichart.canvas.js','../js/com/market_indexes.js','../js/com/chartUtil.js','../js/com/chartDataManager.js','../js/com/minichart.js'],
	'19':['../js/language/en_us/qs_gla_en_us.js','../js/com/gla.js']};*/
	this.widgets={};
	this.bodyHeight=0;
	this._widgetId=0;
	QS.setDataMethod(this.config.dataMethod||'streaming');
};
QS.ModuleBuilder.prototype={
	createWidget:function(config){
		var self=this;
		var widgetProfile=config.widgetProfile||{};
		var widgetCallback=config.widgetCallback||{};
		var id=config.id=this._getWidgetId(config.id);
		var container=config.container=this._getContainer(config);
		if (widgetProfile.fixHeight === false) {// if fixHeight==false, we need reset the callback
			var onOldHeightChange=widgetCallback.onHeightChange;
			var onOldOnload=widgetCallback.onLoad;
			widgetCallback.onHeightChange=function(para){
				//self._setBodyHeight(height,config.top);
				//console.log(config.wType+",changeHeight->"+height);
				if(config.wType!=1){// for chart, no need set the container height
					var height=self._getWidgetHeight(id,para.height);
                    container.style.height=height+'px';
                }
				if(typeof onOldHeightChange=='function'){
					var height=self.$body.outerHeight(true);
					if(self.lastCallbackHeight!=height){
						self.lastCallbackHeight=height;
						if(typeof(onOldHeightChange)=="function")onOldHeightChange({height:self.lastCallbackHeight});
					}
				}
			};
			widgetCallback.onLoad=function(para){
				//self._setBodyHeight(height,config.top);
				//console.log(config.wType+",load->"+height);
				if(config.wType!=1){
					if(para.height){
						var height=self._getWidgetHeight(id,para.height);
						container.style.height=height+'px';
					}
				}
				if(typeof(onOldOnload)=='function'){
					if(typeof(onOldOnload)=="function")onOldOnload({height:self.lastCallbackHeight,cType:config.wType});
					var height=self.$body.outerHeight(true);
                    if(self.lastCallbackHeight!=height){
                        self.lastCallbackHeight=height;
						if(typeof(onOldHeightChange)=="function")onOldHeightChange({height:self.lastCallbackHeight});
                    }
				}
			};
		}
		this._initWidget(config,widgetProfile,widgetCallback);
	},
	_setBodyHeight:function(height,top){
		top=top||0;
		height=height+top+20;//20 is prepare for padding
		if(height!=this.bodyHeight){
			this.bodyHeight=height;
		}
	},
	_getMaxHeight:function(){
		
	},
	_getWidgetHeight:function(id,height){
		if(this.widgets[id]){
			height+=this.widgets[id].toolbarHeight||0;
		}
		
		return height;
		
	},
	_getWidgetId:function(widgetId){
		return widgetId||'qsapi_'+(this._widgetId++);
	},
	_getContainer:function(config){
		var container=document.getElementById(config.containerId);
		var cssConfig={width:config.width||100};
		if(config.wType!=1){
			cssConfig.height=config.height||100;
		}
		if(!container){
			container = document.createElement('div');
			this.body.appendChild(container);
			if(config.y||config.x){
				cssConfig.position='absolute';
				cssConfig.left=config.x || 0;
				cssConfig.top=config.y || 0;
			}
		}
		$(container).css(cssConfig);
		if(typeof container.id=='undefined'||container.id==""){
			container.id = config.id + '_holder';
			
		}
		container.className = "qs-api-holder";
		if(typeof config.constainerClsName!='undefined'){
			container.className+=" "+config.constainerClsName;
		}
		config.container=container;
		return container;
	},
	_initWidget:function(config,widgetProfile,widgetCallback){
		var self=this;
		var fileList=config.fileList||[];//this.widgetFileList[config.wType]||[];
		if(fileList.length==0){// if noneed dynamic to load the file, it will direct create.
			//self._getWidget(config,callback);
			self._generateWidget(config,widgetProfile,widgetCallback);
		}else{
			with({config:config}){
				urlList=config.fileList||[];//this.widgetFileList[config.wType];
				QS_LOADER.LoadFiles(urlList,function(){
					//console.log("run callback "+config.wType);
					//self._getWidget(config,callback);
					self._generateWidget(config,widgetProfile,widgetCallback);
				});
			}
		}
	},
	_generateWidget:function(config,widgetProfile,widgetCallback){
		var hasSearch=config.hasSearch===false?false:true;
		var toolbarHeight=0;
		if(hasSearch){
			toolbarHeight=26;
		}
		if(typeof widgetProfile.width=='undefined'){
			widgetProfile.width=config.width;
		}
		if(typeof widgetProfile.height=='undefined'){
			widgetProfile.height=config.height-toolbarHeight;
		}
		widgetProfile.wType=config.wType;
		var widget=config.onCreateWidget(config.id,config.container.id,widgetProfile,widgetCallback);
		widget.id=config.id;
		widget.toolbarHeight=toolbarHeight;
		if(hasSearch){
			this._createToolbar(config.container,widget);
		}
		if(widgetProfile.wType != 1)QS.Data.register(widget);  // chart not need to register.
		this.widgets[config.id]=widget;
		return widget;
	},
	/*
	_getWidget:function(createFun,config,callback){
		var wType=config.wType;
		var hasSearch=config.hasSearch===false?false:true;
		var widget=null;
		if(hasSearch){
			config.height=config.height-26;
		}
		switch(wType){
			case '0':
				var offsetHeight = config.displayLayout.indexOf('wrap') > -1 ? 32 : 57;
				config.showCascadeMenu=false;
				config.isShowHideChecked=true;
				config.colsViewID=-2;
				config.ticker=MstarData.Watchlist[prelistMap[config.prelist||'dow_jones']]["tickers"].join(",");
				widget=new watchlist({},callback);
				widget.tValidation=new tickerValidation(wType);
				widget.init(config,config.container.id,config.width,config.height+offsetHeight);
			break;
			case '1':
				widget=new chartWebPage(1,config,config.ufg,$(config.container),config.id,config.id,config.showAuto,callback.onTickerChange,true,null);
				widget.acceptTicker = function(){
                    widget.chartComponent.acceptTicker.apply(widget.chartComponent, arguments);
                };
				widget.onChartHeightChange=callback.onHeightChange;
				if(typeof callback.onLoad=='function'){
					callback.onLoad({
						height:widget.el.outerHeight(true)
					});
				}
			break;
			case '2':
				GB_NewsDataManager.defaultStatus = true;
                GB_NewsDataManager.dataURL.newsTitle = "../getNewsTitle.jsp";
                GB_NewsDataManager.dataURL.newsContent = "../getNewsContent.jsp";
				widget=new QS_News(callback);
				widget.tValidation=new tickerValidation(wType);
				widget.init(config.container.id,config);
			break;
			case '10':
				widget=new QS.Quote(config.container,config,callback);
				widget.setTicker(config.ticker);
				widget.tValidation=new tickerValidation(wType);
				widget.init();
			break;
			case '14_1':
				var prefix="../";
				GB_ChartDataManager.dataUrls.intraday = prefix+"quote.jsp?";
				GB_ChartDataManager.dataUrls.historical = prefix+"getStockHistoricalData.jsp?";
				GB_ChartDataManager.dataUrls.fundamental = prefix+"getFundamentalData.jsp?";
				GB_ChartDataManager.dataUrls.minutelyIntraday = prefix+"getMinutelyIntradayData.jsp?";
				GB_ChartDataManager.dataUrls.fundHistorical=prefix+"getFundChartData.jsp?";
				GB_ChartDataManager.dataUrls.exportDataToExcel=prefix+"exportChartDataToExcel.jsp?";
				GB_ChartDataManager.dataUrls.forex = prefix+"getForexHistoricalData.jsp?";
				GB_autoCompleteBoxDataManager.dataUrls = prefix+"acb.jsp";
				widget = new QS_MarketIdx(callback);
                widget.init(config.container.id, config, config.id);
			break;
			case '19':
				widget=new QS_MarketGLA($(config.container),config,callback);
				widget.init();
			break;
		}
		widget.id=config.id;
		if(hasSearch){
			this._createToolbar(config.container,widget);
		}
		QS.Data.register(widget);
		this.widgets[config.id]=widget;
		return widget;
	},*/
	_createToolbar:function(container,widget){
		var html = '<div class="qs-r qs-api-headbar"><input type="text" class="qs-ui-ipt" value="" id="' + widget.id + '_autoBox"><a class="qs-ui-btn qs-autocomplete" href="javascript:void(0)">GO</a></div>';
		var bar = $(html);
		bar.prependTo(container).find('a.qs-autocomplete').bind('click', function(e){
			GB_qsAutoCompleteBox.triggerACB(widget.id + '_autoBox');
		});
		GB_qsAutoCompleteBox.subscription(widget.id + '_autoBox', function(pId){
			widget.acceptTicker(pId);
		});
	},
	showLoading:function(){
		
	},
	hideLoading:function(){
		
	}
};